#include "nr_channel_output.h"

nr_id_t nr_channel_output::g_output_channel_id = 2000;

nr_channel_output::nr_channel_output(nr_channel_output_delegate& data_delegate, 
    nr_channel_operation_delegate& operation_delegate)
    : m_data_delegate(data_delegate)
    , m_operation_delegate(operation_delegate)
{
    m_channel_id = g_output_channel_id++;
}

nr_channel_output::~nr_channel_output()
{
}

void nr_channel_output::fire_data(nr_data *data)
{
    m_data_delegate.on_data(data);
}

void nr_channel_output::fire_event(nr_event *evt)
{
    m_data_delegate.on_event(evt);
}

nr_error_t nr_channel_output::start() 
{ 
    if (m_state == NR_CHANNEL_STATE_STARTED)
        return NR_ERROR_NONE;

    // Just send the process logic to  the up level 
    
    nr_error_t status = m_operation_delegate.on_starting(*this);
    NR_CHECK_RETURN(status);

    // It seems there is nothing need to do here
    m_state = NR_CHANNEL_STATE_STARTED;

    status = m_operation_delegate.on_started(*this);

    return status; 
}

nr_error_t nr_channel_output::pause() 
{ 
    if (m_state == NR_CHANNEL_STATE_PAUSED)
        return NR_ERROR_NONE;

    if (m_state == NR_CHANNEL_STATE_STOPPED)
        return NR_ERROR_NOT_SUPPORT;
    
    // Just send the process logic to  the up level 
    nr_error_t status = m_operation_delegate.on_pausing(*this);
    NR_CHECK_RETURN(status);

    // It seems there is nothing need to do here
    m_state = NR_CHANNEL_STATE_STOPPED;

    status = m_operation_delegate.on_paused(*this);

    return status; 
}

nr_error_t nr_channel_output::stop()
{ 
    if (m_state == NR_CHANNEL_STATE_STOPPED)
        return NR_ERROR_NONE;
    
    // Just send the process logic to  the up level 
    nr_error_t status = m_operation_delegate.on_stopping(*this);
    NR_CHECK_RETURN(status);
    
    // The parent module may stop itself according to its children's status
    m_state = NR_CHANNEL_STATE_STOPPED;
    
    status = m_operation_delegate.on_stopped(*this);

    return status; 
}
